﻿using Newtonsoft.Json;
using System.Diagnostics;
using System.Dynamic;

namespace Wargame_V3_1
{
    public class JudgeInfo : DynamicObject
    {
        // 记录judgeInfo各属性的类型，在JudgeInfoModels.json中定义
        private Dictionary<string, string> __judgeInfoModel = new Dictionary<string, string>();

        // 记录judgeInfo各属性的值，类型由__judgeInfoModel中定义
        private Dictionary<string, object> __judgeInfoData = new Dictionary<string, object>();

        /// <summary>
        /// 构造方法：根据输入的字符串式字典judgeInfoDict，转换属性值类型后，初始化judgeInfo
        /// </summary>
        /// <param name="allJudgeInfoModels">从文件JudgeInfoModels.json中读取的judgeInfo模型</param>
        /// <param name="judgeInfoDict">字符串式字典</param>
        public JudgeInfo(Dictionary<string, Dictionary<string, string>> allJudgeInfoModels, Dictionary<string, string> judgeInfoDict)
        {
            if (judgeInfoDict.ContainsKey("Type"))
            {
                string judgeInfoName = judgeInfoDict["Type"] + "JudgeInfo";
                if (allJudgeInfoModels.ContainsKey(judgeInfoName))// 动作模型是否包含传入的动作
                {
                    __judgeInfoModel = allJudgeInfoModels[judgeInfoName];
                    foreach (KeyValuePair<string, string> item in judgeInfoDict)
                    {
                        if (__judgeInfoModel.ContainsKey(item.Key))
                        {
                            string dataType = __judgeInfoModel[item.Key];
                            dynamic value = ChangeType.ConvertString(item.Value, dataType);
                            __judgeInfoData.Add(item.Key, value);
                        }
                        else
                        {
                            __judgeInfoData.Add(item.Key, item.Value);
                            Trace.TraceWarning($"{item.Key}的属性不在judgeInfo模型中。");
                        }
                    }
                }
                else
                {
                    Trace.TraceError($"JudgeInfoModels中没有{judgeInfoName}的judgeInfo模型");
                    throw new Exception($"JudgeInfoModels中没有{judgeInfoName}的judgeInfo模型");
                }
            }
            else
            {
                Trace.TraceError("输入的judgeInfo有误，没有Type数据");
                throw new Exception("输入的judgeInfo有误，没有Type数据");
            }
        }

        /// <summary>
        /// 构造方法：输入类型良好的字典judgeInfoDict，初始化judgeInfo
        /// </summary>
        /// <param name="allJudgeInfoModels">从文件JudgeInfoModels.json中读取的judgeInfo模型</param>
        /// <param name="judgeInfoDict">类型良好的judgeInfo字典</param>
        public JudgeInfo(Dictionary<string, Dictionary<string, string>> allJudgeInfoModels, Dictionary<string, object> judgeInfoDict)
        {
            if (judgeInfoDict.ContainsKey("Type"))
            {
                string judgeInfoName = judgeInfoDict["Type"] + "JudgeInfo";
                if (allJudgeInfoModels.ContainsKey(judgeInfoName))
                {
                    __judgeInfoModel = allJudgeInfoModels[judgeInfoName];
                    __judgeInfoData = judgeInfoDict;
                }
                else
                {
                    Trace.TraceError($"JudgeInfoModels中没有{judgeInfoName}的judgeInfo模型");
                    throw new Exception($"JudgeInfoModels中没有{judgeInfoName}的judgeInfo模型");
                }
            }
            else
            {
                Trace.TraceError("输入的judgeInfo有误，没有Type数据");
                throw new Exception("输入的judgeInfo有误，没有Type数据");
            }
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (__judgeInfoData.ContainsKey(binder.Name))
            {
                result = __judgeInfoData[binder.Name];
                return true;
            }
            else
            {
                result = null;
                Trace.TraceWarning($"当前judgeInfo中没有属性{binder.Name}");
                return false;
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            string property = binder.Name;
            if (Array.IndexOf(new string[] { "ObjID", "Type" }, property) != -1) // 输入的property是"ObjID"或"Type"，不可更改。
            {
                Trace.TraceWarning($"judgeInfo的属性{property}不可更改");
                return true;
            }
            if (__judgeInfoModel.ContainsKey(property))
            {
                string typeString = __judgeInfoModel[property];
                if (value.GetType() != Type.GetType(ChangeType.ToFullName(typeString))) // 判断value的类型与属性类型是否相符
                {
                    Trace.TraceWarning($"输入{value}的类型与judgeInfo的属性{property}类型不匹配，属性值修改不成功");
                    return true;
                }
                __judgeInfoData[property] = value;
                return true;
            }
            else
            {
                Trace.TraceWarning($"当前judgeInfo中没有属性{property}");
                return false;
            }
        }

        public override string ToString()
        {
            return JsonConvert.SerializeObject(__judgeInfoData);
        }
    }
}
